#include <string>
#include <vector>

using namespace std;


class Solution {
public:
    // KMP Algorithm: O(m + n)
    int strStr(string haystack, string needle) {
        int n = haystack.size(), m = needle.size();
        if (m == 0) return 0;

        // Preprocess needle and construct next
        vector<int> next(m, 0);
        for (int i=1, j=0; i<m; i++) {
            while (j > 0 && needle[i] != needle[j]) {
                // 不相等时，通过 next[j-1] 回退
                // next[j-1] 是前一位置的跳跃 index
                // 当 j==0 或者相等时停止回退
                j = next[j-1];
            }
            if (needle[i] == needle[j]) j++;
            next[i] = j;
        }

        // Utilize next to speed up matching
        // Now the pointer i of haystack will never go backward
        for (int i=0, j=0; i<n; i++) {
            while (j>0 && haystack[i] != needle[j]) {
                j = next[j-1];
            }
            if (haystack[i] == needle[j]) j++;
            if (j == m) return i - m + 1;
        }

        return -1;
    }

    // Brute force: O(mn)
    int strStrBrute(string haystack, string needle) {
        int n = haystack.size(), m = needle.size();
        for (int i = 0; i <= n-m; i++) {
            int j = i, k = 0;
            while (k < m && haystack[j] == needle[k]) {
                j++;
                k++;
            }
            if (k == m) {
                return i;
            }
        }
        return -1;
    }
};
